package com.cloud.salon.gateway.config;

import com.cloud.salon.gateway.bean.UserDetailsServiceImpl;
import com.cloud.salon.gateway.component.filter.JwtAuthenticationTokenFilter;
import com.cloud.salon.gateway.component.filter.LoginAuthenticationFilter;
import com.cloud.salon.gateway.component.handler.*;
import com.cloud.salon.gateway.component.provider.SelfAuthenticationProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.web.cors.CorsUtils;
import org.springframework.web.filter.CharacterEncodingFilter;

/*
 * Spring Security配置
 */
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    // 未登录响应处理器
	@Autowired
    AjaxAuthenticationEntryPointHandler authenticationEntryPoint;
    // 登录成功响应处理器
    @Autowired
    AjaxAuthenticationSuccessHandler authenticationSuccessHandler;
    // 登录失败响应处理器
    @Autowired
    AjaxAuthenticationFailureHandler authenticationFailureHandler;
    // 注销成功响应处理器
    @Autowired
    AjaxLogoutSuccessHandler logoutSuccessHandler;
    // 无权访问响应处理器
    @Autowired
    AjaxAccessDeniedHandler accessDeniedHandler;
    // 自定义安全认证
    @Autowired
    SelfAuthenticationProvider provider;
    // JWT 拦截器
    @Autowired
    JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
	
	@Bean
    UserDetailsService customUserService() {
        return new UserDetailsServiceImpl();
    }
	
    @Override
    protected void configure(AuthenticationManagerBuilder perminssion) throws Exception {
    	perminssion.authenticationProvider(provider);
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    	//添加转码
    	CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();  
    	encodingFilter.setEncoding("UTF-8");  
		encodingFilter.setForceEncoding(true);
		http.addFilterBefore(encodingFilter, CsrfFilter.class);

        http
        .cors()
        	.and()
    	.csrf()
    		.disable()

        .authorizeRequests()
//        	.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()//处理跨域请求中的Preflight请求
        	.antMatchers("/login").permitAll()//对登录接口放行
//    		.antMatchers("/**").permitAll()//对测试接口放行
//        	.anyRequest()
//        	.access("@rbacauthorityservice.hasPermission(request,authentication)")//RBAC动态权限配置
        	.and()
        	
        .formLogin()  //开启登录
        	.and()
        	
        .logout()
        	.logoutSuccessHandler(logoutSuccessHandler)
        	.permitAll();

        // 设置无权访问的处理器
    	http.exceptionHandling()
                .accessDeniedHandler(accessDeniedHandler)
                .authenticationEntryPoint(authenticationEntryPoint);

    	// 插入自定义用户登录检查过滤器
    	http.addFilterAt(loginAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    	// 插入 JWT 过滤器
    	http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
    }
    
    /*
     * @Description 注册自定义的UsernamePasswordAuthenticationFilter
     * @Author wolf--LZH
     */
    @Bean
    LoginAuthenticationFilter loginAuthenticationFilter() throws Exception {
        LoginAuthenticationFilter filter = new LoginAuthenticationFilter();

        //登陆成功
        filter.setAuthenticationSuccessHandler(authenticationSuccessHandler);
        //登陆失败
        filter.setAuthenticationFailureHandler(authenticationFailureHandler);

        //登录接口URL
        filter.setFilterProcessesUrl("/login");

        //这句很关键，重用WebSecurityConfigurerAdapter配置的AuthenticationManager，不然要自己组装AuthenticationManager
        filter.setAuthenticationManager(authenticationManagerBean());
        return filter;
    }


    /*
     * @Description 获取验证管理器
     * @Author wolf--LZH
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}
